﻿using PersistentObject.Common;
using PersistentObject.Common.Schema;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OracleClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PersistentObject.Oracle11GR2
{
    public class Oracle11GR2Dialect : BaseDialect
    {
        public Oracle11GR2Dialect(SchemaConfig config = null)
            : base(config)
        {

        }

        protected override void InitializeNamingPattern()
        {
            NamingPattern = new NamingPatternForOracle();
        }

        public override BaseCriteriaCreator GetCriteriaCreator(Common.Schema.Table mainTable)
        {
            return new CriteriaCreatorForOracle(mainTable, this);
        }

        public override BaseSqlCreator GetSqlCreator(Common.Schema.Table mainTable)
        {
            return new SqlCreatorForOracle(mainTable, this);
        }

        public override System.Data.IDbConnection CreateConnection(string connectionString)
        {
            return new OracleConnection(connectionString);
        }

        public override System.Data.IDbTransaction CreateTransaction(System.Data.IDbConnection connection)
        {
            OracleConnection sqlConnection = (connection as OracleConnection);
            bool wasClosed = sqlConnection != null && sqlConnection.State == ConnectionState.Closed;
            if (wasClosed)
            {
                sqlConnection.Open();
            }
            return sqlConnection.BeginTransaction();
        }

        public override System.Data.IDbCommand CreateCommand(System.Data.IDbTransaction transaction, string sql)
        {
            OracleConnection sqlConnection = (transaction.Connection as OracleConnection);
            OracleTransaction sqlTransaction = (transaction as OracleTransaction);
            if (transaction == null)
            {
                return new OracleCommand(sql, sqlConnection);
            }
            else
            {
                return new OracleCommand(sql, sqlConnection, sqlTransaction);
            }
        }

        public override System.Data.IDbCommand CreateCommand(System.Data.IDbConnection connection, string sql)
        {
            OracleConnection sqlConnection = (connection as OracleConnection);
            return new OracleCommand(sql, sqlConnection);
        }

        public override System.Data.IDbDataAdapter CreateAdapter(System.Data.IDbConnection connection, string sql)
        {
            OracleConnection sqlConnection = (connection as OracleConnection);
            return new OracleDataAdapter(sql, sqlConnection);
        }

        public override System.Data.IDbDataParameter CreateParameter()
        {
            return new OracleParameter();
        }

        public override object RetrieveKeyValue<T>(IDataReader reader, IDbCommand command)
        {
            Table table = SchemaHelper.CreateTable<T>();
            var keyColumnParameterName = NamingPattern.GetSaveParameterName(table.KeyColumn);
            var keyVal = (command as OracleCommand).Parameters[keyColumnParameterName].Value;
            return keyVal;
        }
    }
}
